namespace HotChocolate.Utilities;

public class DictionaryToObjectConverterTests
{
    [Fact]
    public void Convert_Dictionary_FooObject()
    {
        // arrange
        var baz = new Dictionary<string, object>
        {
            ["Number"] = "1.5"
        };

        var bar = new Dictionary<string, object>
        {
            ["State"] = "On",
            ["Bazs"] = new List<object> { baz }
        };

        var foo = new Dictionary<string, object>
        {
            ["text"] = "abc",
            ["BAR"] = bar
        };

        // assert
        var converter = new DictionaryToObjectConverter(
            DefaultTypeConverter.Default);
        var converted = converter.Convert(foo, typeof(Foo));

        // assert
        converted.MatchSnapshot();
    }

    [Fact]
    public void Convert_Dictionary_BarObjectWithArray()
    {
        // arrange
        var baz = new Dictionary<string, object>
        {
            ["Number"] = "1.5"
        };

        var bar = new Dictionary<string, object>
        {
            ["State"] = "On",
            ["Bazs"] = new List<object> { baz },
            ["BazArray"] = new List<object> { baz },
            ["StringArray"] = new List<object> { "a", 1, true }
        };

        // assert
        var converter = new DictionaryToObjectConverter(
            DefaultTypeConverter.Default);
        var converted = converter.Convert(bar, typeof(Bar));

        // assert
        converted.MatchSnapshot();
    }

    [Fact]
    public void Convert_List_ListOfBar()
    {
        // arrange
        var baz = new Dictionary<string, object>
        {
            ["Number"] = "1.5"
        };

        var bar = new Dictionary<string, object>
        {
            ["State"] = "On",
            ["Bazs"] = new List<object> { baz },
            ["BazArray"] = new List<object> { baz },
            ["StringArray"] = new List<object> { "a", 1, true }
        };

        var list = new List<object> { bar };

        // assert
        var converter = new DictionaryToObjectConverter(
            DefaultTypeConverter.Default);
        var converted = converter.Convert(
            list, typeof(ICollection<Bar>));

        // assert
        converted.MatchSnapshot();
    }

    [Fact]
    public void Convert_String_Int()
    {
        // arrange
        const string input = "1";

        // assert
        var converter = new DictionaryToObjectConverter(
            DefaultTypeConverter.Default);
        var converted = converter.Convert(
            input, typeof(int));

        // assert
        converted.MatchSnapshot();
    }

    public class Foo
    {
        public required string Text { get; set; }
        public required Bar Bar { get; set; }
    }

    public class Bar
    {
        public State State { get; set; }
        public required IReadOnlyCollection<Baz> Bazs { get; set; }
        public required Baz[] BazArray { get; set; }
        public required string[] StringArray { get; set; }
    }

    public class Baz
    {
        public decimal Number { get; set; }
    }

    public enum State
    {
        On,
        Off
    }
}
